home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / libc / ds5000.md / bcopy.c < prev    next >
C/C++ Source or Header  |  1991-04-17  |  5KB  |  188 lines

  1. /* 
  2.  * bcopy.c --
  3.  *
  4.  *    Source code for the "bcopy" library routine.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/lib/c/bstring/RCS/bcopy.c,v 1.7 91/03/24 19:03:11 kupfer Exp $ SPRITE (Berkeley)";
  18. #endif not lint
  19.  
  20. /*
  21.  * The following mask is used to detect proper alignment of addresses
  22.  * for doing word operations instead of byte operations.  It is
  23.  * machine-dependent.  If none of the following bits are set in an
  24.  * address, then word-based operations may be used. This value is imported
  25.  * from machparam.h
  26.  */
  27.  
  28. #include "machparam.h"
  29. #include <bstring.h>
  30.  
  31. /*
  32.  * Just because we can do loads from half-word addresses on a sun3 doesn't
  33.  * mean we want to.  Make sure the load address is word-aligned and you'll
  34.  * bcopy twice as fast when the dest is greater than the source.
  35.  */
  36. #ifdef sun3
  37. #define WORDMASK 0x3
  38. #else
  39. #define WORDMASK WORD_ALIGN_MASK
  40. #endif
  41.  
  42. #ifdef KERNEL
  43. #include <vmHack.h>
  44. #endif
  45.  
  46. /*
  47.  *----------------------------------------------------------------------
  48.  *
  49.  * bcopy --
  50.  *
  51.  *    Copy numBytes from *sourcePtr to *destPtr.  This routine is
  52.  *    optimized to do transfers when sourcePtr and destPtr are both
  53.  *    integer-aligned and point to large areas.
  54.  *
  55.  * Results:
  56.  *    There is no return value.  The memory at *destPtr is modified.
  57.  *
  58.  * Side effects:
  59.  *    None.
  60.  *
  61.  *----------------------------------------------------------------------
  62.  */
  63.  
  64. void
  65. bcopy(sourcePtr, destPtr, numBytes)
  66.     char *sourcePtr;        /* Where to copy from */
  67.     char *destPtr;        /* Where to copy to */
  68.     register int numBytes;    /* The number of bytes to copy */
  69. {
  70.     register int *sPtr = (int *) sourcePtr;
  71.     register int *dPtr = (int *) destPtr;
  72.  
  73. #ifdef VM_CHECK_BSTRING_ACCESS
  74.     Vm_CheckAccessible(sourcePtr, numBytes);
  75.     Vm_CheckAccessible(destPtr, numBytes);
  76. #endif
  77.     /*
  78.      * If the destination is below the source then it is safe to copy
  79.      * in the forward direction.  Otherwise, we must start at the top
  80.      * and work down, again optimizing for large transfers.
  81.      */
  82.  
  83.     if (dPtr < sPtr) {
  84.     /*
  85.      * If both the source and the destination point to aligned
  86.      * addresses then copy as much as we can in large transfers.  Once
  87.      * we have less than a whole int to copy then it must be done by
  88.      * byte transfers.  Furthermore, use an expanded loop to avoid
  89.      * the overhead of continually testing loop variables.
  90.      */
  91.     
  92.     if (!((((int) sPtr) | (int) dPtr) & WORDMASK)) {
  93.         while (numBytes >= 16*sizeof(int)) {
  94.         dPtr[0] = sPtr[0];
  95.         dPtr[1] = sPtr[1];
  96.         dPtr[2] = sPtr[2];
  97.         dPtr[3] = sPtr[3];
  98.         dPtr[4] = sPtr[4];
  99.         dPtr[5] = sPtr[5];
  100.         dPtr[6] = sPtr[6];
  101.         dPtr[7] = sPtr[7];
  102.         dPtr[8] = sPtr[8];
  103.         dPtr[9] = sPtr[9];
  104.         dPtr[10] = sPtr[10];
  105.         dPtr[11] = sPtr[11];
  106.         dPtr[12] = sPtr[12];
  107.         dPtr[13] = sPtr[13];
  108.         dPtr[14] = sPtr[14];
  109.         dPtr[15] = sPtr[15];
  110.         sPtr += 16;
  111.         dPtr += 16;
  112.         numBytes -= 16*sizeof(int);
  113.         }
  114.         while (numBytes >= sizeof(int)) {
  115.         *dPtr++ = *sPtr++;
  116.         numBytes -= sizeof(int);
  117.         }
  118.         if (numBytes == 0) {
  119.         return;
  120.         }
  121.     }
  122.     
  123.     /*
  124.      * Copy the remaining bytes.
  125.      */
  126.     
  127.     sourcePtr = (char *) sPtr;
  128.     destPtr = (char *) dPtr;
  129.     while (numBytes > 0) {
  130.         *destPtr++ = *sourcePtr++;
  131.         numBytes--;
  132.     }
  133.     } else {
  134.     /*
  135.      * Handle extra bytes at the top that are due to the transfer
  136.      * length rather than pointer misalignment.
  137.      */
  138.     while (numBytes & WORDMASK) {
  139.         numBytes --;
  140.         destPtr[numBytes] = sourcePtr[numBytes];
  141.     }
  142.     sPtr = (int *) (sourcePtr + numBytes);
  143.     dPtr = (int *) (destPtr + numBytes);
  144.  
  145.     if (!((((int) sPtr) | (int) dPtr) & WORDMASK)) {
  146.         while (numBytes >= 16*sizeof(int)) {
  147.         sPtr -= 16;
  148.         dPtr -= 16;
  149.         dPtr[15] = sPtr[15];
  150.         dPtr[14] = sPtr[14];
  151.         dPtr[13] = sPtr[13];
  152.         dPtr[12] = sPtr[12];
  153.         dPtr[11] = sPtr[11];
  154.         dPtr[10] = sPtr[10];
  155.         dPtr[9] = sPtr[9];
  156.         dPtr[8] = sPtr[8];
  157.         dPtr[7] = sPtr[7];
  158.         dPtr[6] = sPtr[6];
  159.         dPtr[5] = sPtr[5];
  160.         dPtr[4] = sPtr[4];
  161.         dPtr[3] = sPtr[3];
  162.         dPtr[2] = sPtr[2];
  163.         dPtr[1] = sPtr[1];
  164.         dPtr[0] = sPtr[0];
  165.         numBytes -= 16*sizeof(int);
  166.         }
  167.         while (numBytes >= sizeof(int)) {
  168.         *--dPtr = *--sPtr;
  169.         numBytes -= sizeof(int);
  170.         }
  171.         if (numBytes == 0) {
  172.         return;
  173.         }
  174.     }
  175.     
  176.     /*
  177.      * Copy the remaining bytes.
  178.      */
  179.     
  180.     destPtr = (char *) dPtr;
  181.     sourcePtr = (char *) sPtr;
  182.     while (numBytes > 0) {
  183.         *--destPtr = *--sourcePtr;
  184.         numBytes--;
  185.     }
  186.     }
  187. }
  188.